package main
import (
	"fmt"
)
//channel 是引用类型，必须在make之后才能使用
func main(){
	//创建可以放三个int类型的管道
	var intchan chan int
	intchan = make(chan int,3)
	//channel存的是一个地址
	fmt.Printf("channel is :%v, it's address :%p\n",intchan,&intchan)

	//向管道写入数据
	intchan <- 10
	num := 100
	intchan <- num
	intchan <- 200
	//当写入数据时，切记不能超过它的容量，否则会报错deadlock
	//看看管道的长度和cap（容量）
	fmt.Printf("channel len is :%v, cap is %v\n",len(intchan),cap(intchan))
	

	//没办法超过容量存数据，但是可以边读边取！
	num2 := <- intchan  //可以写成 <- intchan 没有接收的变量，相当于取出来后不要了
	fmt.Printf("Get the num is :%v\n",num2)
	//在没有使用协程的情况下，如果管道数据已经取完了，但是还去取的话就会报错deadlock
	fmt.Printf("channel len is :%v, cap is %v\n",len(intchan),cap(intchan))

	

	//如果需要向管道存入各种类型数据，就得用 interface{} ，但是从管道取出来的时候也是一个 interface{}，需要类型断言
	allchan := make(chan interface{},10)
	allchan <- 10
	allchan <- 12.2
	allchan <- "hello golang"
	//如果需要获取管道中间的数据，就得先把前面的推出去
	<- allchan
	<- allchan
	str := <- allchan
	fmt.Printf("Get the str is :%T  ----  %v\n",str,str)	//虽然编译打印出来的 str 的类型是 string 但是实际上仍然是 interface{}
	//var str2 string = str  //这句话会报错！ cannot use str (type interface {}) as type string in assignment 因为这是interface{}类型，所以需要类型断言
	var str2 string = str.(string) //这句是对的。编译通过
	fmt.Printf("Get the str2 is :%T  ----  %v\n",str2,str2)	//虽然编译打印出来的 str 的类型是 string 但是实际上仍然是 interface{}
	
}